import { ShElement } from './ShElement'


export class ShVScroll extends ShElement {

    private $tracker: HTMLElement

    constructor() {
        super()

        this.$shadow.innerHTML = `
            <style>
                :host {
                    position: sticky;
                    top: 0px;
                    width: calc(0.5em + 3px);
                    height: 100%;
                    border-left: var(--border-ctrl);
                    overflow: hidden;                 
                }
                #tracker {
                    position: relative;
                    left: 1px;
                    height: 100px;
                    width: 0.5em;
                    border-radius: 0.25em;
                    background-color: var(--color-border-ctrl);                
                }
            </style>
            <div id="tracker"></div>
        `

        this.$tracker = this.$shadow.getElementById('tracker')!
    }

    /**
     * 设置滚动条的滑块的位置和长度。参数 `top` 和 `height` 都是相对于滚动条高度的百分数。
     */
    public setTracker(top: number, height: number) {
        if (height >= 1) {
            this.addClass('sh-hide')
            return
        }
        
        this.removeClass('sh-hide')

        top = Math.max(0, top)
        if (top + height > 1)
            top = 1 - height

        top = top * this.clientHeight
        height = height * this.clientHeight
        this.$tracker.updateStyle({
            top: top + 'px',
            height: height + 'px',
        })
    }
}
customElements.define('sh-v-scroll', ShVScroll)


export class ShScrollPanel extends ShElement {

    private $content: HTMLElement
    private $vscroll: ShVScroll

    private resizeObserver1: ResizeObserver
    private resizeObserver2: ResizeObserver

    constructor() {
        super()

        this.$shadow.innerHTML = `
            <style>
                :host {
                    flex-grow: 1; 
                    height: 0; /* 关键：允许内容溢出 */
                    overflow: hidden;
                    position: relative;
                    display: flex;
                    align-items: flex-start;
                }
                #content {
                    flex-grow: 1;
                }
            </style>
            <div id="content">
                <slot></slot>
            </div>
            <sh-v-scroll></sh-v-scroll>
        `

        this.$content = this.$shadow.getElementById('content')! as HTMLElement
        this.$vscroll = this.$shadow.querySelector('sh-v-scroll')! as ShVScroll

        this.resizeObserver1 = new ResizeObserver(this.updateTracker.bind(this))
        this.resizeObserver1.observe(this)

        this.resizeObserver2 = new ResizeObserver(this.updateTracker.bind(this))
        this.resizeObserver2.observe(this.$content)

        this.on('wheel', (e) => {
            this.scrollDown(e.deltaY * 0.15)
            e.preventDefault()
        })
    }

    private updateTracker() {
        const panelHeight = this.clientHeight
        const scrollHeight = this.scrollHeight
        const contentTop = this.scrollTop

        if (scrollHeight == 0)
            this.$vscroll.setTracker(0, 1)
        else
            this.$vscroll.setTracker(contentTop / scrollHeight, panelHeight / scrollHeight)
    }

    private scrollDown(delta: number) {
        this.scrollBy({ top: delta })
        this.updateTracker()
    }
}
customElements.define('sh-scroll-panel', ShScrollPanel)